home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Conversion / Convert_RTF / Source / rtfController.m < prev    next >
Text File  |  1993-11-06  |  23KB  |  649 lines

  1. /***********************************************************************\
  2. controller class for Convert RTF which converts between Mac and NeXT rtf formats.
  3. Copyright (C) 1993 David John Burrowes
  4.  
  5. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
  6.  
  7. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  8.  
  9. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10.  
  11. The author, David John Burrowes, can be reached at:
  12.     davidjohn@kira.net.netcom.com
  13.     David John Burrowes
  14.     1926 Ivy #10
  15.     San Mateo, CA 94403-1367
  16. \***********************************************************************/
  17.  
  18. /*
  19. ====================================================================
  20.     This is $Revision: 1.8 $ of this file
  21.     It was last modified by $Author: death $ on $Date: 93/04/04 23:28:27 $
  22. Note that this file was created while using the New Century Schoolbook Roman typeface.  You may find that some things line up strangely if you don't use that family.
  23. $Log:    rtfController.m,v $
  24. Revision 1.8  93/04/04  23:28:27  death
  25. Sun Apr  4 23:28:27 PDT 1993
  26.  
  27. Revision 1.7  93/02/21  12:00:05  death
  28. Sun Feb 21 12:00:05 PST 1993
  29.  
  30. Revision 1.6  93/01/10  08:27:28  death
  31. Sun Jan 10 08:27:28 PST 1993
  32.  
  33. Revision 1.5  93/01/02  23:41:36  death
  34. Sat Jan  2 23:41:36 PST 1993
  35.  
  36. Revision 1.4  93/01/02  13:39:06  death
  37. Sat Jan  2 13:39:06 PST 1993
  38.  
  39. Revision 1.3  92/12/25  16:26:51  death
  40. Fri Dec 25 16:26:51 PST 1992
  41.  
  42. Revision 1.2  92/12/21  07:01:18  death
  43. Mon Dec 21 07:01:18 PST 1992
  44.  
  45. Revision 1.1  92/12/19  08:19:11  death
  46. Sat Dec 19 08:19:10 PST 1992
  47.  
  48.  ====================================================================
  49.  */
  50. #import "rtfController.h"
  51. #import "rtfFile.h"
  52. #import "rtfConverter.h"
  53. #import <appkit/Matrix.h>    // For matrix stuff for preferences setting
  54. #import <libc.h>            // for mkdir  and rmdir
  55. #import    <string.h>        // for strrchr
  56. #import <appkit/Listener.h>        // for the drag-and-drop of files facility
  57. #import <appkit/Speaker.h>        // ibid
  58. #import <appkit/Application.h>        // To get NXApp (I thought that is what defaults was...)
  59. #import <errno.h>                // for errno.
  60.  
  61. #import    "djbflag.h"
  62.  
  63. @implementation    rtfController
  64.  
  65.  
  66. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. //    Routine:        init
  68. //    Parameters:    none
  69. //    Returns:        self
  70. //    Stores:        none
  71. //    Description:
  72. //        This overrides the defalut init method.  and sets up some strings used during
  73. //        some of the user interaction. time. We also create the pict converter instance
  74. //        needed later.
  75. //    Bugs:
  76. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77. - init
  78. {
  79.     static NXDefaultsVector theDefaults =
  80.     {
  81.         {CONVERTTYPE, "YES"},
  82.         {REMOVEUNDERLINE, "NO"},
  83.         {CONVERTTEXT, "ALL"},
  84.         {CONVERTQUOTES, "NO"},
  85.         {CONVERTPICTS, "YES"},
  86.         {DELETEPICTS, "YES"},
  87.         {NULL, NULL}
  88.     };
  89.     CString    tempPref;
  90.  
  91.     [super init];
  92.  
  93.     DefaultsOwner = "RTFConverter";
  94.  
  95.     NXRegisterDefaults(DefaultsOwner, theDefaults);
  96.     
  97.     convertMacRTF = [self   GetBoolPref: CONVERTTYPE];
  98.     StripFirstUL0 = [self   GetBoolPref: REMOVEUNDERLINE];
  99.     //
  100.     //    93.02.15    djb    Changed from a boolean(yes/no) to a string parameter to support
  101.     //                doing no conversion whatsoever.  Checks for yes and no for
  102.     //                backward compatability. =)
  103.     //
  104.     tempPref = [self   GetPref: CONVERTTEXT];
  105.     if ((strcmp(tempPref, "ALL") == 0) || (strcmp(tempPref,"YES") == 0))
  106.         ConvertAllFonts = ConvertAll;
  107.     else if ((strcmp(tempPref, "STANDARD") == 0)|| (strcmp(tempPref,"NO") == 0))
  108.         ConvertAllFonts = ConvertStandard;
  109.     else if (strcmp(tempPref, "NONE") == 0)
  110.         ConvertAllFonts = ConvertNone;
  111.     FreeCString(tempPref);
  112.     ConvertSingleQuotes = [self   GetBoolPref: CONVERTQUOTES];
  113.     ConvertPictData = [self   GetBoolPref: CONVERTPICTS];
  114.     DeletePictData = [self   GetBoolPref: DELETEPICTS];
  115.  
  116.     if (convertMacRTF == YES)
  117.     {
  118.         ConversionString = "Converting Mac rtf to NeXT rtf";
  119.         SourcePrompt = "Mac file:";
  120.         DestPrompt = "NeXT file:";
  121.         if (ForDavidJohnBurrowesOnly == 1)
  122.             DestExtension = ".mac.rtf";
  123.         else
  124.             DestExtension = ".next.rtf";
  125.     }
  126.     else
  127.     {
  128.         ConversionString = "Converting NeXT rtf to Mac rtf";
  129.         SourcePrompt = "NeXT file:";
  130.         DestPrompt = "Mac file:";
  131.         if (ForDavidJohnBurrowesOnly == 1)
  132.             DestExtension = ".next.rtf";
  133.         else
  134.             DestExtension = ".mac.rtf";
  135.     }
  136.     MenuOpen = NO;
  137.  
  138.     converterInst = [[rtfConverter   alloc] init];
  139.     return self;
  140. }
  141.  
  142.  
  143. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. //    Routine:        free
  145. //    Parameters:    none
  146. //    Returns:        ?
  147. //    Stores:        none
  148. //    Description:
  149. //        This cleans up before being deallocated.  (derezed, in tron terms, I suppose).
  150. //    Bugs:
  151. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. - free
  153. {
  154.     if (converterInst != NullInstance)
  155.         [converterInst  free];
  156.     
  157.     return [super free];
  158. }
  159.  
  160. //
  161. //    Added this because the free method is apparently not being called, and we
  162. //    need to kill the converter instance so it can kill the pict converter (so much for
  163. //    modularity, eh?  thank you NeXT/Interface Builder  (or maybe my stupidity)
  164. //
  165. - appWillTerminate: sender
  166. {
  167.     if (converterInst != NullInstance)
  168.         [converterInst  free];
  169.     converterInst = NullInstance;
  170.  
  171.     return [super  appWillTerminate: sender];
  172. }
  173.  
  174. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. //    Routine:        displayPreferences: 
  176. //    Parameters:    the object that called us
  177. //    Returns:        self
  178. //    Stores:        none
  179. //        This is called whenever we need to bring the preferences panel onto the screen.
  180. //        Using the value in our several preferences variables, we set the buttons in
  181. //        the preferences panel to reflect the current values, and then shows the panel.
  182. //    Bugs:
  183. //        As pointed out elsewhere, we don't really need to do this after the first time,
  184. //        since the buttons keep their own state.  So my frakework needs revising!!
  185. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  186. -displayPreferences: target
  187. {
  188.     //
  189.     //    Get the default preference values, and compare judge what buttons to
  190.     //    highlight for the user.
  191.     //
  192.     if (convertMacRTF == YES)
  193.         [MacSourceButton  selectCellWithTag: 1];
  194.     else
  195.         [MacSourceButton  selectCellWithTag: 0];
  196.  
  197.     if (StripFirstUL0 == YES)
  198.         [RemoveUnderlineButton  setIntValue: 1];
  199.     else
  200.         [RemoveUnderlineButton  setIntValue: 0];
  201.     //
  202.     //    93.02.15    djb    Added support for three types of conversion, rather than 2
  203.     //
  204.     if (ConvertAllFonts == ConvertAll)
  205.         [ConvertAllFontsButton  selectCellWithTag: 0];
  206.     else     if (ConvertAllFonts == ConvertStandard)
  207.         [ConvertAllFontsButton  selectCellWithTag: 1];
  208.     else
  209.         [ConvertAllFontsButton  selectCellWithTag: 2];
  210.  
  211.     if (ConvertSingleQuotes == YES)
  212.         [ConvertSingleQuotesButton  selectCellWithTag: 1];
  213.     else
  214.         [ConvertSingleQuotesButton  selectCellWithTag: 0];
  215.  
  216.     if (ConvertPictData == YES)
  217.         [ConvertPictButton  selectCellWithTag: 0];
  218.     else
  219.         [ConvertPictButton  selectCellWithTag: 1];
  220.  
  221.     if (DeletePictData == YES)
  222.         [DeletePictDataButton  selectCellWithTag: 0];
  223.     else
  224.         [DeletePictDataButton  selectCellWithTag: 1];
  225.  
  226.     [prefPanel    makeKeyAndOrderFront:self];
  227.     return self;
  228. }
  229.  
  230.  
  231. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  232. //    Routine:        ChangeConvertSource: 
  233. //    Parameters:    the object that called us
  234. //    Returns:        self;
  235. //    Description:
  236. //        Specifies whether the source is a Mac or a NeXT rtf file.  This is relevant when
  237. //        dealing with drag-and-drop or double clicked files where it is otherwise ambiguous.
  238. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  239. -ChangeConvertSource: sender
  240. {
  241.     if ( [[sender selectedCell] tag] == 1)
  242.     {
  243.         convertMacRTF = YES;
  244.         ConversionString = "Converting Mac rtf to NeXT rtf";
  245.         SourcePrompt = "Mac file:";
  246.         DestPrompt = "NeXT file:";
  247.         if (ForDavidJohnBurrowesOnly == 1)
  248.             DestExtension = ".mac.rtf";
  249.         else
  250.             DestExtension = ".next.rtf";
  251.     }
  252.     else
  253.     {
  254.         convertMacRTF = NO;
  255.         ConversionString = "Converting NeXT rtf to Mac rtf";
  256.         SourcePrompt = "NeXT file:";
  257.         DestPrompt = "Mac file:";
  258.         if (ForDavidJohnBurrowesOnly == 1)
  259.             DestExtension = ".next.rtf";
  260.         else
  261.             DestExtension = ".mac.rtf";
  262.     }
  263.  
  264.     [self   SetBoolPref: CONVERTTYPE To: convertMacRTF];
  265.  
  266.     return self;
  267. }
  268.  
  269.  
  270. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  271. //    Routine:        SetUnderlineRemoval: 
  272. //    Parameters:    the object that called us
  273. //    Returns:        self
  274. //    Description:
  275. //        Sets the boolean preference that indicates whether or not we should remove
  276. //        the first \ul0 in a NeXT rtf file.
  277. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  278. - SetUnderlineRemoval: sender
  279. {
  280.     if (  [sender intValue] == 1)
  281.         StripFirstUL0 = YES;
  282.     else
  283.         StripFirstUL0 = NO;
  284.  
  285.     [self   SetBoolPref: REMOVEUNDERLINE To: StripFirstUL0];
  286.  
  287.     return self;
  288. }
  289.  
  290.  
  291. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  292. //    Routine:        SetFontConversion: 
  293. //    Parameters:    the object that called us
  294. //    Returns:        self
  295. //    Description:
  296. //        Sets the preference that indicates whether or not we should convert
  297. //        text in all fonts, or in the standard fonts, or in none at all.
  298. //    History
  299. //        93.02.15    djb    Added suport for three types of conversion, rather than two.
  300. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  301. - SetFontConversion: sender
  302. {
  303.     if (  [[sender selectedCell] tag]  == 0)
  304.     {
  305.         ConvertAllFonts = ConvertAll;
  306.         [self   SetPref: CONVERTTEXT To: "ALL"];
  307.     }
  308.     else if (  [[sender selectedCell] tag]  == 1)
  309.     {
  310.         ConvertAllFonts = ConvertStandard;
  311.         [self   SetPref: CONVERTTEXT To: "STANDARD"];
  312.     }
  313.     else
  314.     {
  315.         ConvertAllFonts = ConvertNone;
  316.         [self   SetPref: CONVERTTEXT To: "NONE"];
  317.     }
  318.  
  319.     return self;
  320. }
  321.  
  322.  
  323. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  324. //    Routine:        SetSingleQuoteChange: 
  325. //    Parameters:    the object that called us
  326. //    Returns:        self
  327. //    Description:
  328. //        Sets the boolean preference that indicates whether or not we should produce
  329. //        MacStyle single quotes
  330. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  331. - SetSingleQuoteChange: sender
  332. {
  333.     if (  [[sender selectedCell] tag]  == 1)
  334.         ConvertSingleQuotes = YES;
  335.     else
  336.         ConvertSingleQuotes = NO;
  337.  
  338.     [self   SetBoolPref: CONVERTQUOTES To: ConvertSingleQuotes];
  339.     return self;
  340. }
  341.  
  342.  
  343. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  344. //    Routine:        SetPictDataDeletion: 
  345. //    Parameters:    the object that called us
  346. //    Returns:        self
  347. //    Description:
  348. //        Sets the boolean preference that indicates what we should do with PICT data
  349. //        found in the rtf file.  If the value is YES, then we wish to delete the data entirely
  350. //        If it is NO, then we store the pict data in another file
  351. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. - SetPictDataDeletion: sender
  353. {
  354.     if (  [[sender selectedCell] tag]  == 0)
  355.         DeletePictData = YES;
  356.     else
  357.         DeletePictData = NO;
  358.  
  359.     [self   SetBoolPref: DELETEPICTS To: DeletePictData];
  360.     return self;
  361. }
  362.  
  363. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  364. //    Routine:        SetPictConversion: 
  365. //    Parameters:    the object that called us
  366. //    Returns:        self
  367. //    Description:
  368. //        Sets the boolean preference that indicates whether we should try to do a
  369. //        conversion of any pictures we find in the rtf file.  If the value is YES, then
  370. //        we will convert the pictures, otherwise we won't.
  371. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  372. - SetPictConversion: sender
  373. {
  374.     if ( [[sender selectedCell] tag]  == 0)
  375.         ConvertPictData = YES;
  376.     else
  377.         ConvertPictData = NO;
  378.  
  379.     [self   SetBoolPref: CONVERTPICTS To: ConvertPictData];
  380.     return self;
  381. }
  382.  
  383.  
  384.  
  385. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  386. //    Routine:        PrepareForNeXTConversion:
  387. //    Parameters:    the object that called us
  388. //    Returns:        self
  389. //    Description:
  390. //        If the user chooses to convert a NeXT file via the menus, this routine is
  391. //        called first, so we can set up the right conversion options.
  392. //        Note that we store ptrs to all the strings used by the user interface stuff,
  393. //        and substitute ones for this routine, and then restore later.  This is because
  394. //        the default strings are all about what happens when one drags and drops
  395. //        files, wheras this is when someone chooses a menu item.
  396. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  397. - PrepareForNeXTConversion: sender
  398. {
  399.     CString    tempString = ConversionString;
  400.     CString    sourceString = SourcePrompt;
  401.     CString    destString = DestPrompt;
  402.     CString    extenString = DestExtension;
  403.  
  404.     ConversionString = "Converting NeXT rtf to Mac rtf";
  405.     SourcePrompt = "NeXT file:";
  406.     DestPrompt = "Mac file:";
  407.     if (ForDavidJohnBurrowesOnly == 1)
  408.         DestExtension = ".next.rtf";
  409.     else
  410.         DestExtension = ".mac.rtf";
  411.  
  412.     [converterInst    SetConversionDirection: NO];
  413.     MenuOpen = YES;
  414.     [self   PrepareForConversion: self];
  415.  
  416.     ConversionString = tempString;
  417.     SourcePrompt = sourceString;
  418.     DestPrompt = destString;
  419.     DestExtension = extenString;
  420.     return self;
  421. }
  422.  
  423. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  424. //    Routine:        PrepareForMacConversion: 
  425. //    Parameters:    the object that called us
  426. //    Returns:        self
  427. //    Description:
  428. //        If the user chooses to convert a Mac file via the menus, this routine is
  429. //        called first, so we can set up the right conversion options.
  430. //        Note that we store ptrs to all the strings used by the user interface stuff,
  431. //        and substitute ones for this routine, and then restore later.  This is because
  432. //        the default strings are all about what happens when one drags and drops
  433. //        files, wheras this is when someone chooses a menu item.
  434. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  435. - PrepareForMacConversion: sender
  436. {
  437.     CString    tempString = ConversionString;
  438.     CString    sourceString = SourcePrompt;
  439.     CString    destString = DestPrompt;
  440.     CString    extenString = DestExtension;
  441.  
  442.     ConversionString = "Converting Mac rtf to NeXT rtf";
  443.     SourcePrompt = "Mac file:";
  444.     DestPrompt = "NeXT file:";
  445.     if (ForDavidJohnBurrowesOnly == 1)
  446.         DestExtension = ".mac.rtf";
  447.     else
  448.         DestExtension = ".next.rtf";
  449.     
  450.     [converterInst    SetConversionDirection: YES];
  451.     MenuOpen = YES;
  452.     [self   PrepareForConversion: self];
  453.     
  454.     ConversionString = tempString;
  455.     SourcePrompt = sourceString;
  456.     DestPrompt = destString;
  457.     DestExtension = extenString;
  458.     return self;
  459. }
  460.  
  461.  
  462.  
  463. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  464. //    Routine:        openSourceFile: 
  465. //    Parameters:    the name of the file we are to open
  466. //    Returns:        the new file object
  467. //    Stores:        error
  468. //    Description:
  469. //        This simply attempts to open the source file.  If we are successfull, we
  470. //        return it to the caller, otherwise we return an error.
  471. //    Bugs:
  472. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  473. - openSourceFile: (roCString) theFile
  474. {
  475.     Instance    fileInstance;
  476.     [self   ResetResults];
  477.     
  478.     fileInstance = [[rtfFile alloc] initAndUse: theFile];
  479.     if ([fileInstance   GetErrorCode] == ERR_OK)
  480.         [fileInstance   OpenExistingFor: FILE_READ];
  481.     if ([fileInstance   GetErrorCode] != ERR_OK)
  482.     {
  483.         [self   StoreErrorCode: ERR_CANTOPEN
  484.             AndText: "Unable to open that file."];
  485.         [fileInstance   free];
  486.         fileInstance = NullInstance;
  487.     }
  488.     return fileInstance;
  489. }
  490.  
  491.  
  492. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  493. //    Routine:        openDestFile: 
  494. //    Parameters:    the name of the file we are to open
  495. //    Returns:        the new file object
  496. //    Stores:        error
  497. //    Description:
  498. //        This simply attempts to open the destination file.  If we are successfull, we
  499. //        return it to the caller, otherwise we return an error.
  500. //    Bugs:
  501. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  502. - openDestFile: (roCString) theFile
  503. {
  504.     Instance    fileInstance;
  505.     [self   ResetResults];
  506.     
  507.     fileInstance = [[rtfFile alloc] initAndUse: theFile];
  508.     if ([fileInstance   GetErrorCode] == ERR_OK)
  509.         [fileInstance   ClearAndOpenFor: FILE_WRITE];
  510.     if ([fileInstance   GetErrorCode] != ERR_OK)
  511.     {
  512.         [self   StoreErrorCode: ERR_CREATEFAILED
  513.             AndText: "We were not able to create and/or open that file"];
  514.         [fileInstance   free];
  515.         fileInstance = NullInstance;
  516.     }
  517.     return fileInstance;
  518. }
  519.  
  520.  
  521. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  522. //    Routine:        ConvertFrom:To: 
  523. //    Parameters:
  524. //        The file to be converted from
  525. //        the file to be converted to
  526. //    Returns:        self
  527. //    Stores:        error
  528. //    Description:
  529. //        This asks the super class to do any initalizing it needs to, and then goes
  530. //        ahead and asks the converter object to go at it.
  531. //    Bugs
  532. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  533. - ConvertFrom: sourceFile To: destinationFile
  534. {
  535.     [self   ResetResults];
  536.     [super   ConvertFrom: sourceFile To: destinationFile];
  537.     //
  538.     //    If we were started via a menu selection, then the convert
  539.     //    direction has already been set.  Otherwise, we need to set it based on
  540.     //    the default stored in convertMacRTF
  541.     //
  542.     if (MenuOpen == NO)
  543.         [converterInst    SetConversionDirection: convertMacRTF];
  544.     [converterInst    RemoveFirstNeXTUnderline: StripFirstUL0];
  545.     [converterInst    SetTextConversion: ConvertAllFonts];
  546.     [converterInst    ConvertTheSingleQuotes: ConvertSingleQuotes];
  547.     [converterInst    SetPictConversion: ConvertPictData
  548.                     AndDataRemoval: DeletePictData];
  549.  
  550.     [MacConvertCommand    setEnabled: NO];
  551.     [NeXTConvertCommand    setEnabled: NO];
  552.  
  553.     destFileHolder = destinationFile;
  554.     [converterInst    ConvertFrom: sourceFile To: destinationFile];
  555.  
  556.     [MacConvertCommand    setEnabled: YES];
  557.     [NeXTConvertCommand    setEnabled: YES];
  558.     MenuOpen = NO;
  559.  
  560.     if ( [converterInst   GetErrorCode] < ERR_OK)
  561.         [self   StoreErrorCode:  [converterInst   GetErrorCode]
  562.             AndText:  [converterInst   GetErrorText] ];
  563.     else
  564.         [self   StoreErrorCode: ERR_OK
  565.             AndText: "Converted Successfully" ];
  566.     return destFileHolder;
  567. }
  568.  
  569.  
  570. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  571. //    Routine:        MakeDestAnRTFD
  572. //    Parameters:    none
  573. //    Returns:        self
  574. //    Stores:        error
  575. //    Description:
  576. //        This semi-hack routine allows the converter to call us and ask that the destination
  577. //        file be converted into being an rtfd instead of an rtf file.  This involves closeing
  578. //        the rtf file earlier allocated, and creating a directory and subfile for the rtfd.
  579. //        It also involves using a definite hack by way of destFileHolder, which allows
  580. //        us to implicitly change the value that the above routine will return.
  581. //    Bugs
  582. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  583. - MakeDestAnRTFD
  584. {
  585.     id    newFile;
  586.     CString    buffer    = NewCString(1024);
  587.     CString            oldPathName;
  588.     CString    rtfdName;
  589.     CString    pathname;
  590.     Integer    result;
  591.  
  592.     oldPathName = [destFileHolder   GetPathname];
  593.     [destFileHolder   CloseAndDelete];
  594.     //
  595.     //    Create an RTFD folder and file by
  596.     //        1) getting the name for the rtfd folder (the rtf name + d)
  597.     //        2) Creating a directory with this name
  598.     //        3) Create a TXT.rtf file in said directory
  599.     //
  600.     rtfdName = NewCString(strlen(oldPathName) + 1);
  601.     strcat(rtfdName, oldPathName);
  602.     strcat(rtfdName, "d");
  603.     //
  604.     //        2) Creating a directory with the name of the requested font
  605.     //
  606.     errno = 0;
  607.     result = mkdir(rtfdName, 0700 | 0070 | 0007); // strange perms
  608.     if (result != 0)
  609.     {
  610.         sprintf(buffer,  "The rtfd folder could not be created. (mkdir error: %d)", errno);
  611.         [self   StoreErrorCode: ERR_CREATEFAILED  AndText:buffer];
  612.         rmdir(rtfdName);
  613.         newFile = NullInstance;
  614.     }
  615.     else
  616.     {
  617.         //
  618.         //    Allocate space for path to font folder, plus font or font.afm name
  619.         //
  620.         pathname = NewCString(strlen(rtfdName) + 1 +7);
  621.         strcpy(pathname, rtfdName);
  622.         strcat(pathname, "/TXT.rtf");
  623.         //
  624.         //        3) Create a font file in said directory
  625.         //
  626.         newFile =  [[rtfFile alloc] initAndUse: pathname];
  627.         if ([newFile GetErrorCode] == ERR_OK)
  628.             [newFile CreateAndOpenFor: FILE_WRITE];
  629.         if ([newFile GetErrorCode] != ERR_OK)
  630.         {
  631.             [self   StoreErrorCode: ERR_CREATEFAILED
  632.                 AndText: "We failed to create the rtf file"];
  633.             newFile = NullInstance;
  634.             rmdir(rtfdName);
  635.         }
  636.         FreeCString(pathname);
  637.     }
  638.     FreeCString(oldPathName);
  639.     FreeCString(rtfdName);
  640.     FreeCString(buffer);
  641.     destFileHolder = newFile;
  642.     destIsDead = YES;
  643.     return newFile;
  644. }
  645.  
  646.  
  647.  
  648.  
  649. @end